package com.example.demo;

import com.example.api.JobApi;
import com.example.api.JobExecutor;
import com.example.api.dto.ExecuteUserDTO;
import com.example.api.dto.TiggerDTO;
import com.fasterxml.jackson.databind.json.JsonMapper;
import org.microhttp.Handler;
import org.microhttp.Header;
import org.microhttp.Request;
import org.microhttp.Response;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.function.Consumer;

/**
 * @author fanhang
 */
public class MicrohttpHandler implements Handler {
    private static final List<Header> HEADERS = List.of(new Header("Content-Type", "text/json"));

    private final JsonMapper jsonMapper;
    private final JobExecutor jobExecutor;

    public MicrohttpHandler(JsonMapper jsonMapper, JobExecutor jobExecutor) {
        this.jsonMapper = jsonMapper;
        this.jobExecutor = jobExecutor;
    }

    private static Response ok(String content) {
        return ok(content.getBytes(StandardCharsets.UTF_8));
    }

    private static Response ok(byte[] content) {
        return new Response(200, "", HEADERS, content);
    }

    private static Response error(int status, String errorMessage) {
        return new Response(status, "error", HEADERS, errorMessage.getBytes(StandardCharsets.UTF_8));
    }

    @Override
    public void handle(Request request, Consumer<Response> consumer) {
        Response response = null;
        try {
            response = this.dispatch(request.uri(), request.body());
        } catch (UnsupportedOperationException e) {
            response = error(404, e.getMessage());
        } catch (Exception e) {
            response = error(500, "error");
        } finally {
            consumer.accept(response);
        }
    }

    private Response dispatch(String uri, byte[] data) {
        if (uri.endsWith("/")) {
            uri = uri.substring(0, uri.length() - 1);
        }
        if (uri.startsWith(JobApi.EXECUTE_USER)) {
            boolean bo = this.jobExecutor.executeUser(decode(data, ExecuteUserDTO.class));
            return ok(Boolean.valueOf(bo).toString());
        }
        if (uri.startsWith(JobApi.TIGGER)) {
            String result = this.jobExecutor.tigger(decode(data, TiggerDTO.class));
            return ok(result);
        }
        throw new UnsupportedOperationException("不支持");
    }

    private <T> T decode(byte[] data, Class<T> clazz) {
        try {
            return jsonMapper.readValue(data, clazz);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
